package jmine.tec.test.http;

import java.io.BufferedReader;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;

import jmine.tec.utils.collection.IteratorEnumeration;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;

/**
 * @author takeshi
 */
public class MockServletRequest implements ServletRequest, BeanFactoryAware {

    private Map<String, Object> attributes = new HashMap<String, Object>();

    private Map<String, String[]> parameters = new HashMap<String, String[]>();

    private String characterEncoding;

    private BeanFactory beanFactory;

    /**
     * @return the beanFactory
     */
    public BeanFactory getBeanFactory() {
        return this.beanFactory;
    }

    /**
     * @param name String
     * @return object
     */
    public Object getAttribute(final String name) {
        return this.attributes.get(name);
    }

    /**
     * @return {@link Enumeration}
     */
    public Enumeration<String> getAttributeNames() {
        return new IteratorEnumeration<String>(this.attributes.keySet().iterator());
    }

    /**
     * @return string
     */
    public String getCharacterEncoding() {
        return this.characterEncoding;
    }

    /**
     * @return int
     */
    public int getContentLength() {
        return 0;
    }

    /**
     * @return string
     */
    public String getContentType() {
        return null;
    }

    /**
     * @return {@link ServletInputStream}
     */
    public ServletInputStream getInputStream() {
        return null;
    }

    /**
     * @return string
     */
    public String getLocalAddr() {
        try {
            return InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * @return {@link Locale}
     */
    public Locale getLocale() {
        return Locale.getDefault();
    }

    /**
     * @return {@link Enumeration}
     */
    public Enumeration<Locale> getLocales() {
        return new IteratorEnumeration<Locale>(Arrays.asList(Locale.getAvailableLocales()));
    }

    /**
     * @return string
     */
    public String getLocalName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * @return int
     */
    public int getLocalPort() {
        return 0;
    }

    /**
     * @param name String
     * @return String
     */
    public String getParameter(final String name) {
        String[] val = this.getParameterValues(name);
        if (val != null && val.length > 0) {
            return val[0];
        }
        return null;
    }

    /**
     * @return Map
     */
    public Map<?, ?> getParameterMap() {
        return this.parameters;
    }

    /**
     * @return en
     */
    public Enumeration<String> getParameterNames() {
        return new IteratorEnumeration<String>(this.parameters.keySet());
    }

    /**
     * @param name string
     * @return string
     */
    public String[] getParameterValues(final String name) {
        return this.parameters.get(name);
    }

    /**
     * @return string
     */
    public String getProtocol() {
        return "http";
    }

    /**
     * @return null
     */
    public BufferedReader getReader() {
        return null;
    }

    /**
     * @param path string
     * @return string
     */
    public String getRealPath(final String path) {
        return path;
    }

    /**
     * @return string
     */
    public String getRemoteAddr() {
        return this.getLocalAddr();
    }

    /**
     * @return string
     */
    public String getRemoteHost() {
        return this.getLocalName();
    }

    /**
     * @return int
     */
    public int getRemotePort() {
        return 0;
    }

    /**
     * @param path string
     * @return rd
     */
    public RequestDispatcher getRequestDispatcher(final String path) {
        return null;
    }

    /**
     * @return string
     */
    public String getScheme() {
        return null;
    }

    /**
     * @return string
     */
    public String getServerName() {
        return this.getLocalName();
    }

    /**
     * @return int
     */
    public int getServerPort() {
        return 0;
    }

    /**
     * @return boolean
     */
    public boolean isSecure() {
        return false;
    }

    /**
     * @param name string
     */
    public void removeAttribute(final String name) {
        this.attributes.remove(name);
    }

    /**
     * @param name string
     * @param o object
     */
    public void setAttribute(final String name, final Object o) {
        this.attributes.put(name, o);
    }

    /**
     * @param name string
     * @param value string
     */
    public void setParameter(final String name, final String value) {
        this.setParameterValues(name, new String[]{ value });
    }

    /**
     * @param name string
     * @param values array of string
     */
    public void setParameterValues(final String name, final String[] values) {
        this.parameters.put(name, values);
    }

    /**
     * @param env string
     */
    public void setCharacterEncoding(final String env) {
        this.characterEncoding = env;
    }

    /**
     * @param beanFactory the {@link BeanFactory}
     */
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

}
